package com.ruoyi.web.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.web.domain.*;
import com.ruoyi.web.domain.query.CheckDangerQuery;
import com.ruoyi.web.domain.query.DangerPageQuery;
import com.ruoyi.web.domain.query.ReformDangerQuery;
import com.ruoyi.web.domain.query.ShowDangerQuery;
import com.ruoyi.web.domain.vo.DangerBulletinVO;
import com.ruoyi.web.domain.vo.DangerDetailVO;
import com.ruoyi.web.domain.vo.DangerPageVO;
import com.ruoyi.web.domain.vo.DangerStatisticsVO;
import com.ruoyi.web.mapper.*;
import com.ruoyi.web.service.HiddenDangerService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class HiddenDangerServiceImpl implements HiddenDangerService {
    @Autowired
    private BhPlansMapper bhPlansMapper;
    @Autowired
    private BhRiskListMapper bhRiskListMapper;
    @Autowired
    private BhPlansBillMapper bhPlansBillMapper;
    @Autowired
    private BhReportMapper bhReportMapper;
    @Autowired
    private BhPlansCheckMapper bhPlansCheckMapper;
    @Autowired
    private ISysUserService userService;

    /**
     * 获取隐患分页数据
     *
     * @param dangerPageQuery 查询条件
     * @param pageQuery       分页参数
     * @return 隐患分页数据
     */
    @Override
    public TableDataInfo<DangerPageVO> getDangerPage(DangerPageQuery dangerPageQuery, PageQuery pageQuery) {
        String date = dangerPageQuery.getFindTime();
        if (StringUtils.isNotBlank(date)) {
            dangerPageQuery.setFindTimeStart(DateUtil.beginOfDay(DateUtil.parseDate(date)));
            dangerPageQuery.setFindTimeEnd(DateUtil.endOfDay(DateUtil.parseDate(date)));
        }
        QueryWrapper<DangerPageQuery> wrapper = Wrappers.query();
        wrapper.gt("bp.hidden_danger_num", 0);          // 隐患个数大于0
        wrapper.eq("bp.del_flag", 0);
        wrapper.eq(StringUtils.isNotBlank(dangerPageQuery.getIsModel()), "bp.is_model", dangerPageQuery.getIsModel());
        wrapper.eq(StringUtils.isNotBlank(dangerPageQuery.getConstructionOrganization()), "br.construction_organization", dangerPageQuery.getConstructionOrganization());
        wrapper.like(StringUtils.isNotBlank(dangerPageQuery.getWellNo()), "br.well_no", dangerPageQuery.getWellNo());
        wrapper.eq(StringUtils.isNotBlank(dangerPageQuery.getWellType()), "br.well_type", dangerPageQuery.getWellType());
        wrapper.eq(StringUtils.isNotBlank(dangerPageQuery.getRiskStatus()), "bp.risk_status", dangerPageQuery.getRiskStatus());
        // 处理作业项目查询条件
        String projectName = dangerPageQuery.getProjectName();
        if (StringUtils.isNotBlank(projectName)) {
            List<BhRiskList> bhRiskLists = bhRiskListMapper.selectList(new LambdaQueryWrapper<BhRiskList>().eq(BhRiskList::getDelFlag, 0).like(BhRiskList::getName, projectName).orderByAsc(BhRiskList::getId));
            if (CollectionUtils.isNotEmpty(bhRiskLists)) {
                wrapper.and(i -> {
                    bhRiskLists.forEach(x -> {
                        i.or().apply("find_in_set({0},REPLACE(br.project_name, '|', ','))", x.getId());
                    });
                });
            }
        }
        wrapper.between(dangerPageQuery.getFindTimeStart() != null, "bp.find_time", dangerPageQuery.getFindTimeStart(), dangerPageQuery.getFindTimeEnd());
        Page<DangerPageVO> result = bhPlansMapper.getDangerPage(pageQuery.build(), wrapper);
        handleResult(result);
        return TableDataInfo.build(result);
    }

    // 处理分页返回(翻译)
    private void handleResult(Page<DangerPageVO> result) {
        List<DangerPageVO> dangerPageList = result.getRecords();
        if (CollectionUtils.isNotEmpty(dangerPageList)) {
            dangerPageList.forEach(x -> {
                List<String> names = new ArrayList<>();
                List<String> userIds = com.ruoyi.common.utils.StringUtils.str2List(x.getExecutors(), "[|]", true, true);
                if (!org.springframework.util.CollectionUtils.isEmpty(userIds)) {
                    userIds.forEach(y -> {
                        Long userId;
                        try {
                            userId = Long.valueOf(y);
                            SysUser sysUser = userService.selectUserById(userId);
                            if (!Objects.isNull(sysUser)) {
                                names.add(sysUser.getNickName());
                            } else {
                                names.add(y);
                            }
                        } catch (NumberFormatException e) {
                            names.add(y);
                        }

                    });
                }
                x.setExecutors(names.stream().reduce((s1, s2) -> s1 + "|" + s2).orElse(""));
                List<String> ids = com.ruoyi.common.utils.StringUtils.str2List(x.getProjectName(), "[|]", true, true);
                List<BhRiskList> bhRiskLists = bhRiskListMapper.selectList(new LambdaQueryWrapper<BhRiskList>().in(CollectionUtils.isNotEmpty(ids), BhRiskList::getId, ids).orderByAsc(BhRiskList::getId));
                x.setProjectName(bhRiskLists.stream().map(BhRiskList::getName).collect(Collectors.joining("|")));
            });
        }
    }

    /**
     * 获取隐患详情
     *
     * @param id 隐患id
     * @return 隐患详情
     */
    @Override
    public R<DangerDetailVO> getDangerDetail(Integer id) {
        DangerDetailVO result = new DangerDetailVO();
        BhPlans bhPlans = bhPlansMapper.selectOne(new LambdaQueryWrapper<BhPlans>().eq(BhPlans::getDelFlag, 0).eq(BhPlans::getId, id));
        if (Objects.isNull(bhPlans)) {
            return R.fail("未找到对应隐患数据！");
        }
        String reportId = bhPlans.getReportId();
        BhReport bhReport = bhReportMapper.selectOne(new LambdaQueryWrapper<BhReport>().eq(BhReport::getDelFlag, 0).eq(BhReport::getId, reportId));
        if (Objects.isNull(bhReport)) {
            return R.fail("未找到对应作业报备数据！");
        }
        BeanUtils.copyProperties(bhReport, result);
        BeanUtils.copyProperties(bhPlans, result);
        List<String> ids = com.ruoyi.common.utils.StringUtils.str2List(result.getProjectName(), "[|]", true, true);
        List<BhRiskList> bhRiskLists = bhRiskListMapper.selectList(new LambdaQueryWrapper<BhRiskList>().in(CollectionUtils.isNotEmpty(ids), BhRiskList::getId, ids).orderByAsc(BhRiskList::getId));
        result.setProjectName(bhRiskLists.stream().map(BhRiskList::getName).collect(Collectors.joining("|")));
        List<BhPlansBill> bhPlansBills = bhPlansBillMapper.selectList(new LambdaQueryWrapper<BhPlansBill>().eq(BhPlansBill::getDelFlag, 0).eq(BhPlansBill::getPlanId, id));
        List<PlanBill> dangerList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(bhPlansBills)) {
            bhPlansBills.forEach(x -> {
                if ("2".equals(x.getInspectResult())) {
                    PlanBill planBill = new PlanBill();
                    BeanUtils.copyProperties(x, planBill);
                    dangerList.add(planBill);
                }
            });
        }
        result.setDangerList(dangerList);
        List<String> names = new ArrayList<>();
        List<String> userIds = com.ruoyi.common.utils.StringUtils.str2List(result.getExecutors(), "[|]", true, true);
        if (!org.springframework.util.CollectionUtils.isEmpty(userIds)) {
            userIds.forEach(y -> {
                Long userId;
                try {
                    userId = Long.valueOf(y);
                    SysUser sysUser = userService.selectUserById(userId);
                    if (!Objects.isNull(sysUser)) {
                        names.add(sysUser.getNickName());
                    } else {
                        names.add(y);
                    }
                } catch (NumberFormatException e) {
                    names.add(y);
                }

            });
        }
        result.setExecutors(names.stream().reduce((s1, s2) -> s1 + "|" + s2).orElse(""));
        return R.ok(result);
    }

    /**
     * 申请验收
     *
     * @param reformDangerQuery 申请验收请求参数
     * @return 返回
     */
    @Transactional
    @Override
    public R<Void> reformDanger(ReformDangerQuery reformDangerQuery) {
        BhPlans bhPlans = bhPlansMapper.selectOne(new LambdaQueryWrapper<BhPlans>().eq(BhPlans::getDelFlag, 0).eq(BhPlans::getId, reformDangerQuery.getId()));
        if (Objects.isNull(bhPlans)) {
            return R.fail("未找到相关隐患");
        }
        BhPlans upParam = new BhPlans();
        upParam.setId(bhPlans.getId());
        upParam.setRiskStatus("2");
        upParam.setReRectifyReason("");
        upParam.setReRectifyIds("");
        bhPlansMapper.updateById(upParam);
        List<PlanBill> dangerList = reformDangerQuery.getDangerList();
        if (CollectionUtils.isNotEmpty(dangerList)) {
            dangerList.forEach(x -> {
                BhPlansBill modParam = new BhPlansBill();
                BeanUtils.copyProperties(x, modParam);
                modParam.setIsRectify("1");
                bhPlansBillMapper.updateById(modParam);
            });
        }
        return R.ok();
    }

    /**
     * 隐患验收
     *
     * @param checkDangerQuery 验收请求参数
     * @return 返回
     */
    @Transactional
    @Override
    public R<Void> checkDanger(CheckDangerQuery checkDangerQuery) {
        BhPlans bhPlans = bhPlansMapper.selectOne(new LambdaQueryWrapper<BhPlans>().eq(BhPlans::getDelFlag, 0).eq(BhPlans::getId, checkDangerQuery.getId()));
        if (Objects.isNull(bhPlans)) {
            return R.fail("未找到相关隐患");
        }
        BhPlans modParam = new BhPlans();
        modParam.setId(bhPlans.getId());
        String result = checkDangerQuery.getResult();
        if ("1".equals(result)) {
            // 同意
            modParam.setRiskStatus("3");
            modParam.setReRectifyReason("");
            modParam.setReRectifyIds("");
        } else if ("2".equals(result)) {
            // 退回
            modParam.setRiskStatus("5");
            modParam.setReRectifyIds(checkDangerQuery.getReRectifyIds());
            modParam.setReRectifyReason(checkDangerQuery.getReRectifyReason());
        }
        if (bhPlansMapper.updateById(modParam) <= 0) {
            return R.fail("更新状态失败！");
        }
        BhPlansCheck addParam = new BhPlansCheck();
        addParam.setPlanId(bhPlans.getId());
        addParam.setCheckTime(new Date());
        addParam.setResult(result);
        addParam.setRemark(checkDangerQuery.getReRectifyReason());
        addParam.setCheckPeople(String.valueOf(LoginHelper.getUserId()));
        if (bhPlansCheckMapper.insert(addParam) <= 0) {
            return R.fail("操作记录插入失败！");
        }
        return R.ok();
    }

    /**
     * 隐患公示
     *
     * @param showDangerQuery 公示请求参数
     * @return 返回
     */
    @Override
    public R<Void> showDanger(ShowDangerQuery showDangerQuery) {
        BhPlans modParam = new BhPlans();
        BeanUtils.copyProperties(showDangerQuery, modParam);
        modParam.setIsModel("1");
        if (bhPlansMapper.updateById(modParam) <= 0) {
            return R.fail("隐患公示失败！");
        }
        return R.ok();
    }

    /**
     * 获取隐患验收记录
     *
     * @param id 隐患id
     * @return 验收记录
     */
    @Override
    public R<List<BhPlansCheck>> getCheckRecord(Integer id) {
        List<BhPlansCheck> bhPlansChecks = bhPlansCheckMapper.selectList(new LambdaQueryWrapper<BhPlansCheck>().eq(BhPlansCheck::getPlanId, id).orderByDesc(BhPlansCheck::getCheckTime));
        return R.ok(bhPlansChecks);
    }

    /**
     * 获取首页展示隐患
     *
     * @return 隐患数据
     */
    @Override
    public R<List<DangerDetailVO>> getShowList() {
        List<DangerDetailVO> result = new ArrayList<>();
        QueryWrapper<BhPlans> wrapper = Wrappers.query();
        wrapper.eq("bp.is_model", 1);
        wrapper.eq("bp.del_flag", 0);
        List<BhPlans> bhPlans = bhPlansMapper.getShowList(wrapper);
        if (CollectionUtils.isNotEmpty(bhPlans)) {
            for (BhPlans bhPlan : bhPlans) {
                R<DangerDetailVO> dangerDetail = getDangerDetail(bhPlan.getId());
                result.add(dangerDetail.getData());
            }
        }
        return R.ok(result);
    }

    /**
     * 隐患验收分页查询
     *
     * @param dangerPageQuery 查询条件
     * @param pageQuery       分页参数
     * @return 隐患验收数据
     */
    @Override
    public TableDataInfo<DangerPageVO> getCheckPage(DangerPageQuery dangerPageQuery, PageQuery pageQuery) {
        String date = dangerPageQuery.getFindTime();
        if (StringUtils.isNotBlank(date)) {
            dangerPageQuery.setFindTimeStart(DateUtil.beginOfDay(DateUtil.parseDate(date)));
            dangerPageQuery.setFindTimeEnd(DateUtil.endOfDay(DateUtil.parseDate(date)));
        }
        Page<DangerPageVO> result = bhPlansMapper.getCheckPage(pageQuery.build(), dangerPageQuery);
        handleResult(result);
        return TableDataInfo.build(result);
    }

    /**
     * 首页 - 隐患简报数据
     *
     * @return 隐患简报
     */
    @Override
    public R<DangerBulletinVO> getDangerBulletin() {
        DangerBulletinVO result = new DangerBulletinVO();
        Integer reformedNum = 0;        // 已整改
        Integer noReformNum = 0;        // 未整改
        Integer overdueNum = 0;         // 已逾期
        Integer inCheckNum = 0;         // 验收中
        Integer returnNum = 0;          // 已退回
        QueryWrapper<Object> wrapper = Wrappers.query();
        wrapper.gt("bp.hidden_danger_num", 0);
        wrapper.eq("bp.del_flag", 0);
        List<DangerPageVO> dangerList = bhPlansMapper.getDangerBulletin(wrapper);
        if (CollUtil.isNotEmpty(dangerList)) {
            for (DangerPageVO dangerPage : dangerList) {
                String riskStatus = dangerPage.getRiskStatus();
                switch (riskStatus) {
                    case "1":
                        noReformNum++;
                        break;
                    case "2":
                        inCheckNum++;
                        break;
                    case "3":
                        reformedNum++;
                        break;
                    case "4":
                        overdueNum++;
                        break;
                    case "5":
                        returnNum++;
                        break;
                    default:
                        break;
                }
            }
        }
        result.setReformedNum(reformedNum);
        result.setNoReformNum(noReformNum);
        result.setOverdueNum(overdueNum);
        result.setInCheckNum(inCheckNum);
        result.setReturnNum(returnNum);
        return R.ok(result);
    }

    /**
     * 首页 - 获取隐患统计
     *
     * @return 隐患统计数据
     */
    @Override
    public R<List<DangerStatisticsVO>> getDangerStatistics() {
        List<DangerStatisticsVO> result = new ArrayList<>();
        List<DangerStatisticsVO> dangerStatisticsList = bhPlansBillMapper.getDangerStatistics();
        Map<String, List<DangerStatisticsVO>> map = dangerStatisticsList.stream().collect(Collectors.groupingBy(DangerStatisticsVO::getConstructionOrganization));
        map.forEach((key, value) -> {
            DangerStatisticsVO dangerStatistics = new DangerStatisticsVO();
            dangerStatistics.setConstructionOrganization(key);
            Map<String, Long> countMap = value.stream().collect(
                Collectors.groupingBy(DangerStatisticsVO::getHiddenLevel, Collectors.counting()));
            dangerStatistics.setFirstDangerNum(Math.toIntExact(countMap.get("1")));     // 一般隐患
            dangerStatistics.setSecondDangerNum(Math.toIntExact(countMap.get("2")));    // 较大隐患
            dangerStatistics.setThirdDangerNum(Math.toIntExact(countMap.get("3")));     // 重大隐患
            result.add(dangerStatistics);
        });
        return R.ok(result);
    }
}
